package com.snake.service.impl;

import com.snake.enums.Direction;
import com.snake.pojo.GameState;
import com.snake.service.SnakeGameService;
import jakarta.annotation.PostConstruct;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Random;

@Service
public class SnakeGameServiceImpl implements SnakeGameService {
    private static final int GRID_SIZE = 20;
    private GameState gameState;

    @PostConstruct
    public void init() {
        resetGame();
    }

    @Override
    public void resetGame() {
        gameState = new GameState();
        gameState.setGrid(new int[GRID_SIZE][GRID_SIZE]);
        gameState.setSnake(new ArrayList<>());

        // 初始化蛇的位置
        gameState.getSnake().add(new int[]{GRID_SIZE/2, GRID_SIZE/2});
        gameState.setDirection(Direction.RIGHT);
        gameState.setGameOver(false);
        gameState.setScore(0);

        generateFood();
    }

    private void generateFood() {
        Random random = new Random();
        int x, y;
        do {
            x = random.nextInt(GRID_SIZE);
            y = random.nextInt(GRID_SIZE);
        } while (isSnakeCell(x, y));

        gameState.setFood(new int[]{x, y});
    }

    private boolean isSnakeCell(int x, int y) {
        return gameState.getSnake().stream()
                .anyMatch(segment -> segment[0] == x && segment[1] == y);
    }

    @Override
    public GameState move() {
        if (gameState.isGameOver()) {
            return gameState;
        }

        int[] head = gameState.getSnake().get(0);
        int[] newHead = new int[]{head[0], head[1]};

        switch (gameState.getDirection()) {
            case UP: newHead[0]--; break;
            case DOWN: newHead[0]++; break;
            case LEFT: newHead[1]--; break;
            case RIGHT: newHead[1]++; break;
        }

        // 检查碰撞
        if (newHead[0] < 0 || newHead[0] >= GRID_SIZE ||
                newHead[1] < 0 || newHead[1] >= GRID_SIZE ||
                isSnakeCell(newHead[0], newHead[1])) {
            gameState.setGameOver(true);
            return gameState;
        }

        // 移动蛇
        gameState.getSnake().add(0, newHead);

        // 检查是否吃到食物
        if (newHead[0] == gameState.getFood()[0] && newHead[1] == gameState.getFood()[1]) {
            gameState.setScore(gameState.getScore() + 10);
            generateFood();
        } else {
            // 如果没有吃到食物，移除尾部
            gameState.getSnake().remove(gameState.getSnake().size() - 1);
        }

        return gameState;
    }

    @Override
    public void changeDirection(Direction newDirection) {
        // 防止180度转弯
        if ((gameState.getDirection() == Direction.UP && newDirection != Direction.DOWN) ||
                (gameState.getDirection() == Direction.DOWN && newDirection != Direction.UP) ||
                (gameState.getDirection() == Direction.LEFT && newDirection != Direction.RIGHT) ||
                (gameState.getDirection() == Direction.RIGHT && newDirection != Direction.LEFT)) {
            gameState.setDirection(newDirection);
        }
    }

    @Override
    public GameState getGameState() {
        return gameState;
    }
}
